//
// SimpleHashTableTest.cpp
//

#include "SimpleHashTable.h"
#include <assert.h>
#include <sstream>
#include <iostream>


void testInsert()
{
	std::string s1("str1");
	std::string s2("str2");
	SimpleHashTable<std::string, int> hashTable;
	assert(!hashTable.exists(s1));
	hashTable[s1] = 13;	// equal to: hashTable.insert(s1, 13);
	assert(hashTable.exists(s1));
	assert(hashTable.get(s1) == 13);
	int retVal = 0;

	assert(hashTable.get(s1, retVal));
	assert(retVal == 13);
	try
	{
		hashTable.insert(s1, 22);
	}
	catch (std::exception&)
	{
		assert("duplicate insert must fail");
	}
	try
	{
		hashTable.get(s2);
	}
	catch (std::exception&)
	{
		assert("getting a non inserted item must fail");
	}

	assert(!hashTable.exists(s2));
	hashTable.insert(s2, 13);
	assert(hashTable.exists(s2));
}


void testUpdate()
{
	// add code for second test here
	std::string s1("str1");
	std::string s2("str2");
	SimpleHashTable<std::string, int> hashTable;
	hashTable.insert(s1, 13);
	hashTable.update(s1, 14);
	assert(hashTable.exists(s1));
	assert(hashTable.get(s1) == 14);
	int retVal = 0;

	assert(hashTable.get(s1, retVal));
	assert(retVal == 14);

	// updating a non existing item must work too
	hashTable.update(s2, 15);
	assert(hashTable.get(s2) == 15);
}


void testOverflow()
{
	SimpleHashTable<std::string, int> hashTable(31);
	for (int i = 0; i < 31; ++i)
	{  
		std::stringstream ss;
		ss << i; 
		hashTable.insert(ss.str(), i*i);
	}

	for (int i = 0; i < 31; ++i)
	{
		std::stringstream ss;
		ss << i;  
		std::string tmp = ss.str();
		assert(hashTable.exists(tmp));
		assert(hashTable.get(tmp) == i*i);
	}
}


void testSize()
{
	SimpleHashTable<std::string, int> hashTable(13);
	assert(hashTable.size() == 0);
	unsigned int h1 = hashTable.insert("1", 1);
	assert(hashTable.size() == 1);
	unsigned int h2 = hashTable.update("2", 2);
	assert(hashTable.size() == 2);
	hashTable.clear();
	assert(hashTable.size() == 0);
}


void testResize()
{
	SimpleHashTable<std::string, int> hashTable(13);
	assert(hashTable.size() == 0);
	hashTable.resize(2467);
	for (int i = 0; i < 1024; ++i)
	{
		std::stringstream ss;
		ss << i;  
		hashTable.insert(ss.str(), i*i);
	}
	hashTable.resize(3037);

	for (int i = 0; i < 1024; ++i)
	{
		std::stringstream ss;
		ss << i;  
		std::string tmp = ss.str();
		assert(hashTable.exists(tmp));
		assert(hashTable.get(tmp) == i*i);
	}
}


int main()
{
 	testInsert();
 	testUpdate();
	testOverflow();
 	testSize();
 	testResize();
	std::cin.get();
	return 0;
}

